using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.MultiTenancy;
using Matrix.Notification.Domain.Shared.Notifications;

namespace Matrix.Notification.Domain.Notifications
{
    /// <summary>
    /// 通知批次聚合根实体
    /// </summary>
    public class NotificationBatch : FullAuditedAggregateRoot<Guid>, IMultiTenant
    {
        /// <summary>
        /// 租户ID
        /// </summary>
        public virtual Guid? TenantId { get; protected set; }

        /// <summary>
        /// 批次名称
        /// </summary>
        public virtual string Name { get; protected set; } = string.Empty;

        /// <summary>
        /// 批次描述
        /// </summary>
        public virtual string? Description { get; protected set; }

        /// <summary>
        /// 批次类型
        /// </summary>
        public virtual NotificationBatchType Type { get; protected set; }

        /// <summary>
        /// 通知类型
        /// </summary>
        public virtual NotificationType NotificationType { get; protected set; }

        /// <summary>
        /// 通知优先级
        /// </summary>
        public virtual NotificationPriority Priority { get; protected set; }

        /// <summary>
        /// 使用渠道
        /// </summary>
        public virtual string Channels { get; protected set; } = string.Empty;

        /// <summary>
        /// 发送者ID
        /// </summary>
        public virtual Guid? SenderId { get; protected set; }

        /// <summary>
        /// 发送者姓名
        /// </summary>
        public virtual string? SenderName { get; protected set; }

        /// <summary>
        /// 模板ID
        /// </summary>
        public virtual Guid? TemplateId { get; protected set; }

        /// <summary>
        /// 模板名称
        /// </summary>
        public virtual string? TemplateName { get; protected set; }

        /// <summary>
        /// 批次状态
        /// </summary>
        public virtual NotificationBatchStatus Status { get; protected set; }

        /// <summary>
        /// 总接收者数量
        /// </summary>
        public virtual int TotalRecipients { get; protected set; }

        /// <summary>
        /// 已发送数量
        /// </summary>
        public virtual int SentCount { get; protected set; }

        /// <summary>
        /// 送达数量
        /// </summary>
        public virtual int DeliveredCount { get; protected set; }

        /// <summary>
        /// 失败数量
        /// </summary>
        public virtual int FailedCount { get; protected set; }

        /// <summary>
        /// 已读数量
        /// </summary>
        public virtual int ReadCount { get; protected set; }

        /// <summary>
        /// 已确认数量
        /// </summary>
        public virtual int ConfirmedCount { get; protected set; }

        /// <summary>
        /// 调度时间
        /// </summary>
        public virtual DateTime? ScheduledTime { get; protected set; }

        /// <summary>
        /// 开始发送时间
        /// </summary>
        public virtual DateTime? StartedTime { get; protected set; }

        /// <summary>
        /// 完成时间
        /// </summary>
        public virtual DateTime? CompletedTime { get; protected set; }

        /// <summary>
        /// 预估完成时间
        /// </summary>
        public virtual DateTime? EstimatedCompletionTime { get; protected set; }

        /// <summary>
        /// 发送间隔（毫秒）
        /// </summary>
        public virtual int SendIntervalMs { get; protected set; }

        /// <summary>
        /// 批次大小
        /// </summary>
        public virtual int BatchSize { get; protected set; }

        /// <summary>
        /// 最大重试次数
        /// </summary>
        public virtual int MaxRetryCount { get; protected set; }

        /// <summary>
        /// 并发数
        /// </summary>
        public virtual int Concurrency { get; protected set; }

        /// <summary>
        /// 接收者列表（文件路径或JSON）
        /// </summary>
        public virtual string RecipientList { get; protected set; } = string.Empty;

        /// <summary>
        /// 接收者过滤条件（JSON格式）
        /// </summary>
        public virtual string? RecipientFilters { get; protected set; }

        /// <summary>
        /// 通用参数（JSON格式）
        /// </summary>
        public virtual string? Parameters { get; protected set; }

        /// <summary>
        /// 附件列表（JSON格式）
        /// </summary>
        public virtual string? Attachments { get; protected set; }

        /// <summary>
        /// 失败原因
        /// </summary>
        public virtual string? FailureReason { get; protected set; }

        /// <summary>
        /// 进度百分比
        /// </summary>
        public virtual double ProgressPercentage { get; protected set; }

        /// <summary>
        /// 每秒发送速率
        /// </summary>
        public virtual double SendRatePerSecond { get; protected set; }

        /// <summary>
        /// 平均发送时间（毫秒）
        /// </summary>
        public virtual double AverageSendTimeMs { get; protected set; }

        /// <summary>
        /// 批次标签
        /// </summary>
        public virtual string Tags { get; protected set; } = string.Empty;

        /// <summary>
        /// 业务数据（JSON格式）
        /// </summary>
        public virtual string? BusinessData { get; protected set; }

        /// <summary>
        /// 批次设置（JSON格式）
        /// </summary>
        public virtual string? Settings { get; protected set; }

        /// <summary>
        /// 是否允许重复发送
        /// </summary>
        public virtual bool AllowDuplicates { get; protected set; }

        /// <summary>
        /// 是否跳过已退订用户
        /// </summary>
        public virtual bool SkipUnsubscribed { get; protected set; }

        /// <summary>
        /// 是否静默发送
        /// </summary>
        public virtual bool IsSilent { get; protected set; }

        /// <summary>
        /// 是否需要确认
        /// </summary>
        public virtual bool RequiresConfirmation { get; protected set; }

        /// <summary>
        /// 确认截止时间
        /// </summary>
        public virtual DateTime? ConfirmationDeadline { get; protected set; }

        /// <summary>
        /// 批次编码
        /// </summary>
        public virtual string BatchCode { get; protected set; } = string.Empty;

        /// <summary>
        /// 外部批次ID
        /// </summary>
        public virtual string? ExternalBatchId { get; protected set; }

        /// <summary>
        /// 关联实体ID
        /// </summary>
        public virtual Guid? RelatedEntityId { get; protected set; }

        /// <summary>
        /// 关联实体类型
        /// </summary>
        public virtual string? RelatedEntityType { get; protected set; }

        /// <summary>
        /// 是否已暂停
        /// </summary>
        public virtual bool IsPaused { get; protected set; }

        /// <summary>
        /// 暂停原因
        /// </summary>
        public virtual string? PauseReason { get; protected set; }

        /// <summary>
        /// 暂停时间
        /// </summary>
        public virtual DateTime? PausedTime { get; protected set; }

        /// <summary>
        /// 恢复时间
        /// </summary>
        public virtual DateTime? ResumedTime { get; protected set; }

        protected NotificationBatch()
        {
        }

        /// <summary>
        /// 创建新批次
        /// </summary>
        public NotificationBatch(
            Guid id,
            Guid? tenantId,
            string name,
            NotificationBatchType type,
            NotificationType notificationType,
            NotificationPriority priority,
            string recipientList,
            string? description = null,
            Guid? templateId = null,
            string? templateName = null)
            : base(id)
        {
            TenantId = tenantId;
            Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: 200);
            Type = type;
            NotificationType = notificationType;
            Priority = priority;
            RecipientList = Check.NotNullOrWhiteSpace(recipientList, nameof(recipientList));
            Description = description;
            TemplateId = templateId;
            TemplateName = templateName;
            Status = NotificationBatchStatus.Draft;
            TotalRecipients = 0;
            SentCount = 0;
            DeliveredCount = 0;
            FailedCount = 0;
            ReadCount = 0;
            ConfirmedCount = 0;
            SendIntervalMs = 1000; // 默认1秒间隔
            BatchSize = 100; // 默认批次大小
            MaxRetryCount = 3;
            Concurrency = 5; // 默认并发数
            ProgressPercentage = 0;
            SendRatePerSecond = 0;
            AverageSendTimeMs = 0;
            AllowDuplicates = false;
            SkipUnsubscribed = true;
            IsSilent = false;
            RequiresConfirmation = false;
            IsPaused = false;
            BatchCode = GenerateBatchCode();
        }

        /// <summary>
        /// 更新基本信息
        /// </summary>
        public virtual NotificationBatch UpdateInfo(
            string name,
            string? description = null,
            string? tags = null)
        {
            if (Status != NotificationBatchStatus.Draft)
            {
                throw new UserFriendlyException("只能修改草稿状态的批次");
            }

            Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: 200);
            Description = description;
            Tags = tags ?? string.Empty;
            return this;
        }

        /// <summary>
        /// 设置发送渠道
        /// </summary>
        public virtual NotificationBatch SetChannels(params NotificationChannel[] channels)
        {
            if (channels == null || channels.Length == 0)
            {
                throw new ArgumentException("至少需要指定一个发送渠道", nameof(channels));
            }

            var channelList = new List<string>();
            foreach (var channel in channels)
            {
                channelList.Add(channel.ToString());
            }

            Channels = string.Join(",", channelList);
            return this;
        }

        /// <summary>
        /// 设置发送参数
        /// </summary>
        public virtual NotificationBatch SetSendParameters(
            int sendIntervalMs = 1000,
            int batchSize = 100,
            int maxRetryCount = 3,
            int concurrency = 5)
        {
            if (Status != NotificationBatchStatus.Draft)
            {
                throw new UserFriendlyException("只能修改草稿状态的批次");
            }

            SendIntervalMs = sendIntervalMs > 0 ? sendIntervalMs : 1000;
            BatchSize = batchSize > 0 ? batchSize : 100;
            MaxRetryCount = maxRetryCount >= 0 ? maxRetryCount : 3;
            Concurrency = concurrency > 0 ? concurrency : 5;
            return this;
        }

        /// <summary>
        /// 设置调度时间
        /// </summary>
        public virtual NotificationBatch Schedule(DateTime scheduledTime)
        {
            if (Status != NotificationBatchStatus.Draft && Status != NotificationBatchStatus.Ready)
            {
                throw new UserFriendlyException("只能调度草稿或就绪状态的批次");
            }

            ScheduledTime = scheduledTime;
            Status = NotificationBatchStatus.Scheduled;
            return this;
        }

        /// <summary>
        /// 设置接收者数量
        /// </summary>
        public virtual NotificationBatch SetTotalRecipients(int totalRecipients)
        {
            if (totalRecipients < 0)
            {
                throw new ArgumentException("接收者数量不能小于0", nameof(totalRecipients));
            }

            TotalRecipients = totalRecipients;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 准备发送
        /// </summary>
        public virtual NotificationBatch PrepareForSending()
        {
            if (Status != NotificationBatchStatus.Draft && Status != NotificationBatchStatus.Scheduled)
            {
                throw new UserFriendlyException("只能准备草稿或已调度状态的批次");
            }

            if (!ScheduledTime.HasValue || ScheduledTime.Value <= DateTime.UtcNow)
            {
                Status = NotificationBatchStatus.Ready;
            }
            else
            {
                Status = NotificationBatchStatus.Scheduled;
            }

            return this;
        }

        /// <summary>
        /// 开始发送
        /// </summary>
        public virtual NotificationBatch StartSending()
        {
            if (Status != NotificationBatchStatus.Ready && Status != NotificationBatchStatus.Scheduled)
            {
                throw new UserFriendlyException("只能开始发送就绪或已调度状态的批次");
            }

            Status = NotificationBatchStatus.Sending;
            StartedTime = DateTime.UtcNow;
            IsPaused = false;
            return this;
        }

        /// <summary>
        /// 标记为已发送
        /// </summary>
        public virtual NotificationBatch MarkAsSent(int count = 1)
        {
            if (Status != NotificationBatchStatus.Sending && Status != NotificationBatchStatus.Paused)
            {
                throw new UserFriendlyException("只能标记发送中或暂停状态的批次");
            }

            SentCount += count;
            UpdateProgress();
            UpdateSendRate();
            return this;
        }

        /// <summary>
        /// 标记为已送达
        /// </summary>
        public virtual NotificationBatch MarkAsDelivered(int count = 1)
        {
            if (Status != NotificationBatchStatus.Sending && Status != NotificationBatchStatus.Paused)
            {
                throw new UserFriendlyException("只能标记发送中或暂停状态的批次");
            }

            DeliveredCount += count;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 标记为发送失败
        /// </summary>
        public virtual NotificationBatch MarkAsFailed(int count = 1, string? failureReason = null)
        {
            if (Status != NotificationBatchStatus.Sending && Status != NotificationBatchStatus.Paused)
            {
                throw new UserFriendlyException("只能标记发送中或暂停状态的批次");
            }

            FailedCount += count;
            FailureReason = failureReason;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 标记为已读
        /// </summary>
        public virtual NotificationBatch MarkAsRead(int count = 1)
        {
            ReadCount += count;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 标记为已确认
        /// </summary>
        public virtual NotificationBatch MarkAsConfirmed(int count = 1)
        {
            ConfirmedCount += count;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 完成发送
        /// </summary>
        public virtual NotificationBatch Complete()
        {
            if (Status != NotificationBatchStatus.Sending && Status != NotificationBatchStatus.Paused)
            {
                throw new UserFriendlyException("只能完成发送中或暂停状态的批次");
            }

            Status = NotificationBatchStatus.Completed;
            CompletedTime = DateTime.UtcNow;
            IsPaused = false;
            UpdateProgress();
            return this;
        }

        /// <summary>
        /// 取消批次
        /// </summary>
        public virtual NotificationBatch Cancel(string? reason = null)
        {
            if (Status == NotificationBatchStatus.Completed || Status == NotificationBatchStatus.Cancelled)
            {
                throw new UserFriendlyException("无法取消已完成或已取消的批次");
            }

            Status = NotificationBatchStatus.Cancelled;
            FailureReason = reason;
            CompletedTime = DateTime.UtcNow;
            IsPaused = false;
            return this;
        }

        /// <summary>
        /// 暂停批次
        /// </summary>
        public virtual NotificationBatch Pause(string? reason = null)
        {
            if (Status != NotificationBatchStatus.Sending)
            {
                throw new UserFriendlyException("只能暂停发送中的批次");
            }

            Status = NotificationBatchStatus.Paused;
            IsPaused = true;
            PauseReason = reason;
            PausedTime = DateTime.UtcNow;
            return this;
        }

        /// <summary>
        /// 恢复批次
        /// </summary>
        public virtual NotificationBatch Resume()
        {
            if (Status != NotificationBatchStatus.Paused)
            {
                throw new UserFriendlyException("只能恢复暂停状态的批次");
            }

            Status = NotificationBatchStatus.Sending;
            IsPaused = false;
            PauseReason = null;
            ResumedTime = DateTime.UtcNow;
            return this;
        }

        /// <summary>
        /// 设置接收者列表
        /// </summary>
        public virtual NotificationBatch SetRecipientList(string recipientList)
        {
            if (Status != NotificationBatchStatus.Draft)
            {
                throw new UserFriendlyException("只能修改草稿状态的接收者列表");
            }

            RecipientList = Check.NotNullOrWhiteSpace(recipientList, nameof(recipientList));
            return this;
        }

        /// <summary>
        /// 设置接收者过滤条件
        /// </summary>
        public virtual NotificationBatch SetRecipientFilters(string recipientFilters)
        {
            if (Status != NotificationBatchStatus.Draft)
            {
                throw new UserFriendlyException("只能修改草稿状态的接收者过滤条件");
            }

            RecipientFilters = recipientFilters;
            return this;
        }

        /// <summary>
        /// 设置通用参数
        /// </summary>
        public virtual NotificationBatch SetParameters(string parameters)
        {
            Parameters = parameters;
            return this;
        }

        /// <summary>
        /// 设置附件
        /// </summary>
        public virtual NotificationBatch SetAttachments(string attachments)
        {
            Attachments = attachments;
            return this;
        }

        /// <summary>
        /// 设置业务数据
        /// </summary>
        public virtual NotificationBatch SetBusinessData(string businessData)
        {
            BusinessData = businessData;
            return this;
        }

        /// <summary>
        /// 设置关联实体信息
        /// </summary>
        public virtual NotificationBatch SetRelatedEntity(Guid? entityId, string? entityType)
        {
            RelatedEntityId = entityId;
            RelatedEntityType = entityType;
            return this;
        }

        /// <summary>
        /// 设置确认要求
        /// </summary>
        public virtual NotificationBatch SetConfirmation(bool requiresConfirmation, DateTime? confirmationDeadline = null)
        {
            RequiresConfirmation = requiresConfirmation;
            ConfirmationDeadline = confirmationDeadline;
            return this;
        }

        /// <summary>
        /// 设置发送选项
        /// </summary>
        public virtual NotificationBatch SetSendOptions(
            bool allowDuplicates = false,
            bool skipUnsubscribed = true,
            bool isSilent = false)
        {
            AllowDuplicates = allowDuplicates;
            SkipUnsubscribed = skipUnsubscribed;
            IsSilent = isSilent;
            return this;
        }

        /// <summary>
        /// 获取发送渠道列表
        /// </summary>
        public virtual List<NotificationChannel> GetChannels()
        {
            var channels = new List<NotificationChannel>();
            if (!string.IsNullOrEmpty(Channels))
            {
                var channelStrings = Channels.Split(',');
                foreach (var channelString in channelStrings)
                {
                    if (Enum.TryParse<NotificationChannel>(channelString.Trim(), out var channel))
                    {
                        channels.Add(channel);
                    }
                }
            }
            return channels;
        }

        /// <summary>
        /// 检查是否支持指定渠道
        /// </summary>
        public virtual bool SupportsChannel(NotificationChannel channel)
        {
            return GetChannels().Contains(channel);
        }

        /// <summary>
        /// 计算成功率
        /// </summary>
        public virtual double CalculateSuccessRate()
        {
            if (SentCount == 0)
            {
                return 0;
            }

            return (double)DeliveredCount / SentCount * 100;
        }

        /// <summary>
        /// 计算读取率
        /// </summary>
        public virtual double CalculateReadRate()
        {
            if (DeliveredCount == 0)
            {
                return 0;
            }

            return (double)ReadCount / DeliveredCount * 100;
        }

        /// <summary>
        /// 计算确认率
        /// </summary>
        public virtual double CalculateConfirmationRate()
        {
            if (!RequiresConfirmation || DeliveredCount == 0)
            {
                return 0;
            }

            return (double)ConfirmedCount / DeliveredCount * 100;
        }

        /// <summary>
        /// 估算剩余时间
        /// </summary>
        public virtual TimeSpan? EstimateRemainingTime()
        {
            if (Status != NotificationBatchStatus.Sending || SentCount == 0)
            {
                return null;
            }

            var remainingCount = TotalRecipients - SentCount;
            var sendRatePerSecond = CalculateCurrentSendRate();

            if (sendRatePerSecond <= 0)
            {
                return null;
            }

            var remainingSeconds = remainingCount / sendRatePerSecond;
            return TimeSpan.FromSeconds(remainingSeconds);
        }

        /// <summary>
        /// 计算当前发送速率
        /// </summary>
        private double CalculateCurrentSendRate()
        {
            if (!StartedTime.HasValue)
            {
                return 0;
            }

            var elapsedTime = (DateTime.UtcNow - StartedTime.Value).TotalSeconds;
            return elapsedTime > 0 ? SentCount / elapsedTime : 0;
        }

        /// <summary>
        /// 更新进度
        /// </summary>
        private void UpdateProgress()
        {
            if (TotalRecipients > 0)
            {
                ProgressPercentage = (double)SentCount / TotalRecipients * 100;
            }
        }

        /// <summary>
        /// 更新发送速率
        /// </summary>
        private void UpdateSendRate()
        {
            SendRatePerSecond = CalculateCurrentSendRate();

            // 更新平均发送时间
            if (SentCount > 0 && StartedTime.HasValue)
            {
                var elapsedTime = (DateTime.UtcNow - StartedTime.Value).TotalMilliseconds;
                AverageSendTimeMs = elapsedTime / SentCount;
            }
        }

        /// <summary>
        /// 生成批次编码
        /// </summary>
        protected virtual string GenerateBatchCode()
        {
            return $"BATCH_{DateTime.UtcNow:yyyyMMdd}_{Guid.NewGuid().ToString("N")[..8].ToUpper()}";
        }
    }

    /// <summary>
    /// 通知批次类型枚举
    /// </summary>
    public enum NotificationBatchType
    {
        /// <summary>
        /// 立即发送
        /// </summary>
        Immediate = 1,

        /// <summary>
        /// 调度发送
        /// </summary>
        Scheduled = 2,

        /// <summary>
        /// 定期发送
        /// </summary>
        Recurring = 3,

        /// <summary>
        /// 触发发送
        /// </summary>
        Triggered = 4,

        /// <summary>
        /// 批量发送
        /// </summary>
        Bulk = 5,

        /// <summary>
        /// 个性化发送
        /// </summary>
        Personalized = 6,

        /// <summary>
        /// 测试发送
        /// </summary>
        Test = 7
    }

    /// <summary>
    /// 通知批次状态枚举
    /// </summary>
    public enum NotificationBatchStatus
    {
        /// <summary>
        /// 草稿
        /// </summary>
        Draft = 1,

        /// <summary>
        /// 就绪
        /// </summary>
        Ready = 2,

        /// <summary>
        /// 已调度
        /// </summary>
        Scheduled = 3,

        /// <summary>
        /// 发送中
        /// </summary>
        Sending = 4,

        /// <summary>
        /// 已暂停
        /// </summary>
        Paused = 5,

        /// <summary>
        /// 已完成
        /// </summary>
        Completed = 6,

        /// <summary>
        /// 已取消
        /// </summary>
        Cancelled = 7,

        /// <summary>
        /// 发送失败
        /// </summary>
        Failed = 8
    }
}